<template>
  <div>
    <!-- 上传组件 -->
    <!--
      1. action 必传 需要给一个后端接口地址, elementui会帮你发送请求
      我们不需要它自动发请求, 我们将来自己发送请求, 此时给空 不让他报错
      2. list-type 文件列表的类型, 此处选择的是以照片墙的形式进行展示
      3. file-list 文件列表数组
      4. limit 限制用户上传图片数量
      5. on-preview 当你点击预览的+号时, 会自动触发, 接收一个函数, 会把点击的图片文件作为参数传递
      6. on-remove
        当你点击垃圾篓的时候会自动触发
        会接收一个函数, 函数会有两个参数: file, fileList
        file: 是被删除的那个文件对象
        fileList: 返回最新的文件列表 (结构中的列表, 不是数据中的列表)
      7. http-request
       覆盖默认的上传行为，可以自定义上传的实现
       接收的是一个函数 函数接收一个参数: 对象 (obj.file -- 就是要上传的文件对象)
       一旦配置了自定义上传, 当选择一张图片时, 默认会以本地预览的形式展示图片
       类似于: blob:http://localhost:8888/bc04f586-b0c1-48bd-9102-46f7ddf32926
       临时生成一个本地图片用于预览, 增强用户体验
      8. on-change
       文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
       接收的是一个函数 function(file, fileList)
      9. before-upload
       图片文件在真正上传之前触发, 接收的是一个函数   function(file)
       一般用于校验图片的格式或者图片的大小...
    -->
    <el-upload
      :class="{disabled: isDisabled}"
      action=""
      list-type="picture-card"
      :limit="limit"
      :file-list="fileList"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-change="handleChange"
      :before-upload="handleBeforeUpload"
      :http-request="handleUpload"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <!-- 对话框 -->
    <el-dialog title="预览图片" :visible="dialogVisible" @close="dialogVisible=false">
      <img :src="dialogImageUrl" alt="" style="width:100%">
    </el-dialog>
  </div>
</template>

<script>
import COS from 'cos-js-sdk-v5' // 导入腾讯云的包(sdk)
// 创建一个腾讯云对象存储实例
const cos = new COS({
  SecretId: 'AKIDYw5ybx2qNdcKlunPkob7LJ9nBI8h02mF', // 身份识别ID
  SecretKey: 'IJ4YmiNlrgHgqkNimZ5KIyNUKtWsxlJb' // 身份秘钥
})

export default {
  name: 'UploadImage',
  props: {
    // 1. 限制上传图片的数量
    limit: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      // 1. 上传文件列表
      fileList: [],
      // 2. 对话框中图片标签的url地址
      dialogImageUrl: '',
      // 3. 控制对话框的显示/隐藏
      dialogVisible: false
    }
  },
  computed: {
    // 1. 控制加号显示和隐藏
    isDisabled() {
      return this.limit <= this.fileList.length
    },
    // 2. 判断当前组件是否已经完成上传 true/false
    isAllUploadSuccess() {
      return this.fileList.every(item => item.status === 'success')
    }
  },
  methods: {
    // 1. 预览图片
    handlePictureCardPreview(file) {
      // console.log(file)
      // 1.1 显示预览对话框
      this.dialogVisible = true
      // 1.2 赋值url地址
      this.dialogImageUrl = file.url
    },
    // 2. 删除图片文件
    // 默认值删除结构, 希望同时同步到数据层面
    handleRemove(file, fileList) {
      // console.log(file, fileList)
      // 方式一:
      this.fileList = [...fileList]
      // 方式二:
      // this.fileList = this.fileList.filter(item => item.uid !== file.uid)
    },
    // 3. 自定义上传图片文件
    handleUpload(obj) {
      // console.log('我要上传图片了...', obj.file)

      // 3.1 根据上传的对象的uid去数组中找到该对象
      const uid = obj.file.uid
      const fileObj = this.fileList.find(item => item.uid === uid)

      // 必须在上传之前把status的值改成uploading, 不然不会显示进度条
      fileObj.status = 'uploading'

      cos.putObject({
        Bucket: 'hrsass-49-cs-1312445828', /* 填入您自己的存储桶，必须字段 */
        Region: 'ap-shanghai', /* 存储桶所在地域，例如ap-beijing，必须字段 */
        Key: 'hrsass-49-' + (+new Date()) + '-' + obj.file.name, /* 存储在桶里的对象键（例如1.jpg，a/b/test.txt），必须字段 */
        Body: obj.file, /* 必须，上传文件对象，可以是input[type="file"]标签选择本地文件后得到的file对象 */
        onProgress: (progressData) => {
          // console.log(progressData)
          // 设置上传的进度
          fileObj.percentage = parseInt(progressData.percent * 100)
        }
      }, (err, data) => {
        // 此处一定要改成箭头函数, 否则拿不到this
        // console.log(err || data)
        if (err) {
          this.$message.error('上传图片操作失败~')
          return
        }

        // 3.2 更新上传的状态
        // 为了让用户感知到上传的进度, 可以做一个1s延迟
        setTimeout(() => {
          fileObj.status = 'success'
        }, 1000)

        // 3.3 用图片的线上url地址替换本地的临时地址
        fileObj.url = 'https://' + data.Location
      })
    },
    // 4. 处理文件改变, 结构和数据同步
    handleChange(file, fileList) {
      // console.log(file, fileList)
      // 4.1 把结构和数据同步 参数fileList是控制结构的
      this.fileList = [...fileList]
    },
    // 5 .处理文件上传前的格式和大小校验
    handleBeforeUpload(file) {
      // console.log(file)
      // 5.1 限制图片大小为2M以内
      // 1MB = 1024KB  1KB = 1024B
      const isLt2M = file.size / 1024 / 1024 <= 2
      if (!isLt2M) {
        this.$message.error('上传的图片大小不能超过2MB!')
        return false
      }

      // 5.2 正常
      return true
    }
  }
}
</script>

<style lang="scss" scoped>
  .disabled{
     // 深度穿透
     ::v-deep {
      .el-upload--picture-card {
         display: none;
      }
     }
  }
</style>
